package com.study.service;

import com.study.Constants.PermissionConstants;
import com.study.common.ResultCode;
import com.study.dao.PermissionApiDao;
import com.study.dao.PermissionDao;
import com.study.dao.PermissionMenuDao;
import com.study.dao.PermissionPointDao;
import com.study.dto.PermissionDto;
import com.study.entity.system.Permission;
import com.study.entity.system.PermissionApi;
import com.study.entity.system.PermissionMenu;
import com.study.entity.system.PermissionPoint;
import com.study.exception.CommonException;
import com.study.util.IdWorker;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author wfw
 * @Date 2020/07/13 13:46
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PermissionService {
    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private PermissionMenuDao permissionMenuDao;

    @Autowired
    private PermissionPointDao permissionPointDao;

    @Autowired
    private PermissionApiDao permissionApiDao;

    @Autowired
    private IdWorker idWorker;

    /**
     * 保存权限
     */
    public void save(PermissionDto permissionDto) {
        String id = String.valueOf(idWorker.nextId());

        permissionDto.setId(id);

        Permission permission = new Permission();
        BeanUtils.copyProperties(permissionDto, permission);

        // 根据类型构造不同的资源对象(菜单,按钮,api)
        int type = permission.getType();
        switch (type) {
            case PermissionConstants
                    .PERMISSION_MENU: {
                PermissionMenu permissionMenu = new PermissionMenu();
                BeanUtils.copyProperties(permissionDto, permissionMenu);
                permissionMenuDao.save(permissionMenu);
                break;
            }
            case PermissionConstants
                    .PERMISSION_POINT: {
                PermissionPoint permissionPoint = new PermissionPoint();
                BeanUtils.copyProperties(permissionDto, permissionPoint);
                permissionPointDao.save(permissionPoint);
                break;
            }
            case PermissionConstants
                    .PERMISSION_API: {
                PermissionApi permissionApi = new PermissionApi();
                BeanUtils.copyProperties(permissionDto, permissionApi);
                permissionApiDao.save(permissionApi);
                break;
            }
            default:
                throw new CommonException(ResultCode.FAIL);
        }

        permissionDao.save(permission);
    }

    /**
     * 更新
     */
    public void update(PermissionDto permissionDto) {

        Permission permission = new Permission();
        // 只允许修改 权限名称、权限描述、可见状态
        permission.setName(permissionDto.getName());
        permission.setDescription(permissionDto.getDescription());
        permission.setEnVisible(permissionDto.getEnVisible());

        // 根据类型构造不同的资源对象(菜单,按钮,api)
        int type = permission.getType();
        switch (type) {
            case PermissionConstants
                    .PERMISSION_MENU: {
                PermissionMenu permissionMenu = new PermissionMenu();
                BeanUtils.copyProperties(permissionDto, permissionMenu);
                permissionMenuDao.save(permissionMenu);
                break;
            }
            case PermissionConstants
                    .PERMISSION_POINT: {
                PermissionPoint permissionPoint = new PermissionPoint();
                BeanUtils.copyProperties(permissionDto, permissionPoint);
                permissionPointDao.save(permissionPoint);
                break;
            }
            case PermissionConstants
                    .PERMISSION_API: {
                PermissionApi permissionApi = new PermissionApi();
                BeanUtils.copyProperties(permissionDto, permissionApi);
                permissionApiDao.save(permissionApi);
                break;
            }
            default:
                throw new CommonException(ResultCode.FAIL);
        }

        permissionDao.save(permission);
    }

    /**
     * 根据id查询权限
     */
    public PermissionDto findById(String id) throws CommonException {
        Permission permission = permissionDao.findById(id).get();
        int type = permission.getType();

        Object object = new Object();
        if (type == PermissionConstants.PERMISSION_MENU) {
            object = permissionMenuDao.findById(id).get();
        } else if (type == PermissionConstants.PERMISSION_POINT) {
            object = permissionPointDao.findById(id).get();
        } else if (type == PermissionConstants.PERMISSION_API) {
            object = permissionApiDao.findById(id).get();
        } else {
            throw new CommonException(ResultCode.FAIL);
        }
        PermissionDto permissionDto = new PermissionDto();
        BeanUtils.copyProperties(permission, permissionDto);
        BeanUtils.copyProperties(object, permissionDto);
        return permissionDto;
    }

    /**
     * type     :   查询全部权限列表
     * 0 : 菜单 + 按钮(权限点)    1 ： 菜单  2 : 按钮(权限点) 3 ： API接口
     * enVisible :
     * 0 ： 查询SaaS平台的最高权限   1 ： 查询企业的权限
     */
    public List<Permission> findAll(Permission param) {
        // 查询条件
        Specification<Permission> specification = new Specification<Permission>() {
            @Override
            public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();

                //根据父id查询
                if (!StringUtils.isEmpty(param.getPid())) {
                    list.add(criteriaBuilder.equal(root.get("pid").as(String.class), param.getPid()));
                }

                //根据enVisible查询
                if (!StringUtils.isEmpty(param.getEnVisible())) {
                    list.add(criteriaBuilder.equal(root.get("enVisible").as(String.class), param.getEnVisible()));
                }

                //根据类型type进行查询
                if (!StringUtils.isEmpty(param.getType())) {
                    CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("type"));

                    if (0 == param.getType()) {
                        in.value(1).value(2);
                    } else {
                        in.value(param.getType());
                    }
                    list.add(in);
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
        return permissionDao.findAll(specification);
    }

    /**
     * 根据id删除权限
     */
    public void deleteById(String id) throws CommonException {
        //通过传递的权限id查询权限
        Permission permission = permissionDao.findById(id).get();
        permissionDao.delete(permission);
        //根据类型构造不同的资源
        int type = permission.getType();
        switch (type) {
            case PermissionConstants.PERMISSION_MENU:
                permissionMenuDao.deleteById(id);
                break;
            case PermissionConstants.PERMISSION_POINT:
                permissionPointDao.deleteById(id);
                break;
            case PermissionConstants.PERMISSION_API:
                permissionApiDao.deleteById(id);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
    }

    /**
     * 查询所有企业可以看到的menu
     */
    public List<Permission> getMenus() {
        List<Permission> permissions = permissionDao.findByTypeAndEnVisible(1, "1");
        return permissions;
    }
}
